﻿namespace PlugNT.Pack.Imager
{
    using System;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.IO;

    /// <summary>
    /// program design：agui 
    /// datetime      ：2009.08.05
    /// art aegis     ：http://dreamman_yx.blog.163.com
    /// qq number     ：354990393
    /// </summary>
    public class WaterMark
    {
        private string _waterimagepath;
        private string _savepath;
        private Stream _imgstream;
        private int _transparency;
        private int _quality;
        private int _waterstatus;
        private string _watertext;
        private string _waterfontname;
        private int _waterfontsize;

        public WaterMark()
        {
        }
        /// <summary>
        /// 水印图片路径
        /// </summary>
        public string WaterImagePath
        {
            get { return _waterimagepath; }
            set
            {
                _waterimagepath = value;
            }
        }
        /// <summary>
        /// 图片保存路径
        /// </summary>
        public string SavePath
        {
            get { return _savepath; }
            set
            {
                _savepath = value;
            }
        }
        /// <summary>
        /// 上传图片流对象
        /// </summary>
        public Stream ImgStream
        {
            get { return _imgstream; }
            set
            {
                _imgstream = value;
            }
        }
        /// <summary>
        /// 图片透明度1-10，10为不透明
        /// </summary>
        public int Transparency
        {
            get { return _transparency; }
            set
            {
                _transparency = value;
            }
        }
        /// <summary>
        /// 图片质量0-100之间
        /// </summary>
        public int Quality
        {
            get { return _quality; }
            set
            {
                _quality = value;
            }
        }
        /// <summary>
        /// 水印图片位置0为不处理1-9个位置
        /// </summary>
        public int Waterstatus
        {
            get { return _waterstatus; }
            set
            {
                _waterstatus = value;
            }
        }
        /// <summary>
        /// 水印文字
        /// </summary>
        public string WaterText
        {
            get { return _watertext; }
            set
            {
                _watertext = value;
            }
        }
        /// <summary>
        /// 水印文字字体名
        /// </summary>
        public string WaterFontName
        {
            get { return _waterfontname; }
            set
            {
                _waterfontname = value;
            }
        }
        /// <summary>
        /// 水印文字大小
        /// </summary>
        public int WaterFontSize
        {
            get { return _waterfontsize; }
            set
            {
                _waterfontsize = value;
            }
        }


        /// <summary>
        /// 加文字水印，注意，这里的代码和以下加图片水印的代码不能共存 
        /// </summary>
        /// <returns></returns>
        public string SaveStringWater() //string str, string colorname, float x, float y
        {

            if (SavePath == null || SavePath == "")
            {
                return "保存图片的路径不能为空！";
            }
            if (Quality == 0)
            {
                return "要设置水印的图片质量不能为空！";
            }
            if (WaterText == null)
            {
                return "水印文字不能为空！";
            }
            if (WaterFontName == null)
            {
                return "水印文字字体名不能为空！";
            }
            if (WaterFontSize == 0)
            {
                return "水印文字大小不能为空！";
            }
            if (ImgStream == null)
            {
                return "水印图片流对象不能为空！";
            }

            int quality = Quality;                     //附件图片质量0-100之间
            int watermarkStatus = Waterstatus;         //图片附件添加水印的位置，0-9，0为不使用
            string filename = SavePath;
            string watermarkText = WaterText;
            string fontname = WaterFontName;
            int fontsize = WaterFontSize;
            Image img = Image.FromStream(ImgStream);
            Font drawFont = new Font(fontname, fontsize, FontStyle.Regular, GraphicsUnit.Pixel);
            float xpos = 0;
            float ypos = 0;
            SizeF crSize;

            //如果原图片是索引像素格式之列的，则需要转换
            if (IsPixelFormatIndexed(img.PixelFormat))
            {
                Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);
                using (Graphics g2 = Graphics.FromImage(bmp))
                {
                    g2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g2.DrawImage(img, 0, 0);
                }

                System.Drawing.Graphics g3 = System.Drawing.Graphics.FromImage(bmp);
                crSize = g3.MeasureString(watermarkText, drawFont);
                switch (watermarkStatus)
                {
                    case 1:
                        xpos = (float)img.Width * (float).01;
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 2:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 3:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 4:
                        xpos = (float)img.Width * (float).01;
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 5:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 6:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 7:
                        xpos = (float)img.Width * (float).01;
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                    case 8:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                    case 9:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                }

                g3.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + 1, ypos + 1);
                g3.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos);
                bmp.Save(filename);
                g3.Dispose();
                bmp.Dispose();

                img.Dispose();
                return "";
            }
            else
            {
                Graphics g = Graphics.FromImage(img);
                crSize = g.MeasureString(watermarkText, drawFont);
                switch (watermarkStatus)
                {
                    case 1:
                        xpos = (float)img.Width * (float).01;
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 2:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 3:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = (float)img.Height * (float).01;
                        break;
                    case 4:
                        xpos = (float)img.Width * (float).01;
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 5:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 6:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = ((float)img.Height * (float).50) - (crSize.Height / 2);
                        break;
                    case 7:
                        xpos = (float)img.Width * (float).01;
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                    case 8:
                        xpos = ((float)img.Width * (float).50) - (crSize.Width / 2);
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                    case 9:
                        xpos = ((float)img.Width * (float).99) - crSize.Width;
                        ypos = ((float)img.Height * (float).99) - crSize.Height;
                        break;
                }

                //			System.Drawing.StringFormat StrFormat = new System.Drawing.StringFormat();
                //			StrFormat.Alignment = System.Drawing.StringAlignment.Center;
                //
                //			g.DrawString(watermarkText, drawFont, new System.Drawing.SolidBrush(System.Drawing.Color.White), xpos + 1, ypos + 1, StrFormat);
                //			g.DrawString(watermarkText, drawFont, new System.Drawing.SolidBrush(System.Drawing.Color.Black), xpos, ypos, StrFormat);
                g.DrawString(watermarkText, drawFont, new SolidBrush(Color.White), xpos + 1, ypos + 1);
                g.DrawString(watermarkText, drawFont, new SolidBrush(Color.Black), xpos, ypos);

                ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo ici = null;
                foreach (ImageCodecInfo codec in codecs)
                {
                    if (codec.MimeType.IndexOf("jpeg") > -1)
                    {
                        ici = codec;
                    }
                }
                EncoderParameters encoderParams = new EncoderParameters();
                long[] qualityParam = new long[1];
                if (quality < 0 || quality > 100)
                {
                    quality = 80;
                }
                qualityParam[0] = quality;

                EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
                encoderParams.Param[0] = encoderParam;

                if (ici != null)
                {
                    img.Save(filename, ici, encoderParams);
                }
                else
                {
                    img.Save(filename);
                }
                g.Dispose();
                img.Dispose();

                return "";
            }
        }
        /// <summary>
        /// 加图片水印
        /// </summary>
        /// <returns></returns>
        public string SaveImageWater()
        {
            if (WaterImagePath == null || WaterImagePath == "")
            {
                return "水印的图片路径不能为空！";
            }
            if (!File.Exists(WaterImagePath))
            {
                return "水印的图片路径错误！";
            }
            if (SavePath == null || SavePath == "")
            {
                return "保存图片的路径不能为空！";
            }
            if (Transparency == 0)
            {
                return "要设置水印的图片透明度不能为空！";
            }
            if (Quality == 0)
            {
                return "要设置水印的图片质量不能为空！";
            }
            if (Waterstatus == 0)
            {
                return "水印图片位置不能为空！";
            }
            if (ImgStream == null)
            {
                return "水印图片流对象不能为空！";
            }

            int watermarkTransparency = Transparency; //图片透明度1-10，10为不透明
            int quality = Quality;              //附件图片质量0-100之间
            int watermarkStatus = Waterstatus;         //图片附件添加水印的位置，0-9，0为不使用
            string filename = SavePath;
            string watermarkFilename = WaterImagePath;
            Image img = Image.FromStream(ImgStream);
            Image watermark = new Bitmap(watermarkFilename);

            int xpos = 0;
            int ypos = 0;

            switch (watermarkStatus)
            {
                case 1:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 2:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 3:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)(img.Height * (float).01);
                    break;
                case 4:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 5:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 6:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).50) - (watermark.Height / 2));
                    break;
                case 7:
                    xpos = (int)(img.Width * (float).01);
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 8:
                    xpos = (int)((img.Width * (float).50) - (watermark.Width / 2));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
                case 9:
                    xpos = (int)((img.Width * (float).99) - (watermark.Width));
                    ypos = (int)((img.Height * (float).99) - watermark.Height);
                    break;
            }

            //如果原图片是索引像素格式之列的，则需要转换
            if (IsPixelFormatIndexed(img.PixelFormat))
            {
                Bitmap bmp = new Bitmap(img.Width, img.Height, PixelFormat.Format32bppArgb);
                using (Graphics g2 = Graphics.FromImage(bmp))
                {
                    g2.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    g2.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                    g2.DrawImage(img, 0, 0);
                }

                System.Drawing.Graphics g3 = System.Drawing.Graphics.FromImage(bmp);

                g3.DrawImage(watermark, new System.Drawing.Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, System.Drawing.GraphicsUnit.Pixel);
                bmp.Save(filename);
                g3.Dispose();
                bmp.Dispose();

                img.Dispose();
                watermark.Dispose();
                return "";
            }
            else
            {
                Graphics g = Graphics.FromImage(img);
                //设置高质量插值法
                //g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
                //设置高质量,低速度呈现平滑程度
                //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;


                if (watermark.Height >= img.Height || watermark.Width >= img.Width)
                {
                    return "水印图片宽度和高度不能大于上传图片的值！";
                }

                ImageAttributes imageAttributes = new ImageAttributes();
                ColorMap colorMap = new ColorMap();

                colorMap.OldColor = Color.FromArgb(255, 0, 255, 0);
                colorMap.NewColor = Color.FromArgb(0, 0, 0, 0);
                ColorMap[] remapTable = { colorMap };

                imageAttributes.SetRemapTable(remapTable, ColorAdjustType.Bitmap);

                float transparency = 0.5F;
                if (watermarkTransparency >= 1 && watermarkTransparency <= 10)
                {
                    transparency = (watermarkTransparency / 10.0F);
                }

                float[][] colorMatrixElements = {
												new float[] {1.0f,  0.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  1.0f,  0.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  1.0f,  0.0f, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  transparency, 0.0f},
												new float[] {0.0f,  0.0f,  0.0f,  0.0f, 1.0f}
											};

                ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

                imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);



                g.DrawImage(watermark, new Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, GraphicsUnit.Pixel, imageAttributes);
                //g.DrawImage(watermark, new System.Drawing.Rectangle(xpos, ypos, watermark.Width, watermark.Height), 0, 0, watermark.Width, watermark.Height, System.Drawing.GraphicsUnit.Pixel);

                ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
                ImageCodecInfo ici = null;
                foreach (ImageCodecInfo codec in codecs)
                {
                    if (codec.MimeType.IndexOf("jpeg") > -1)
                    {
                        ici = codec;
                    }
                }
                EncoderParameters encoderParams = new EncoderParameters();
                long[] qualityParam = new long[1];
                if (quality < 0 || quality > 100)
                {
                    quality = 80;
                }
                qualityParam[0] = quality;

                EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qualityParam);
                encoderParams.Param[0] = encoderParam;

                if (ici != null)
                {
                    img.Save(filename, ici, encoderParams);
                }
                else
                {
                    img.Save(filename);
                }
                g.Dispose();
                img.Dispose();
                watermark.Dispose();
                imageAttributes.Dispose();
                return "";
            }
        }

        private static PixelFormat[] indexedPixelFormats = { PixelFormat.Undefined, PixelFormat.DontCare, PixelFormat.Format16bppArgb1555, PixelFormat.Format1bppIndexed, PixelFormat.Format4bppIndexed, PixelFormat.Format8bppIndexed };
        private static bool IsPixelFormatIndexed(PixelFormat imgPixelFormat)
        {
            foreach (PixelFormat pf in indexedPixelFormats)
            {
                if (pf.Equals(imgPixelFormat)) return true;
            }
            return false;
        }

        #region contact me
        public static string Help()
        {
            return @"mailto:354990393@qq.com";
        }
        #endregion
    }
}

